BearZPY Blog

Hi, nice to meet you

BearZPY's avatar BearZPY

Android APK 裁剪体积

Android APK 裁剪体积

目前编译生成的 APK 体积越来越大,就有了缩小 APK 大小的需求,本文整理了 APK 裁剪的基本方案。

主要方向

对 APK 大小进行裁剪有下面几个基本切入点

  • 图片资源
  • 代码(jar 包,so 库)
  • 资源混淆

对这几个切入点,可以利用 Android Studio 提供的工具 Analyze APK 来分析各项资源在 APK 大小中所占有的比例,还可以用来比较裁剪前后的 APK 差异,可以直观的观察到裁剪效果。

下面是 Analyze APK 中的几个名词概念:

  • raw file size:文件在磁盘中解压后的大小
  • download file size:文件在 Google Play 中压缩后的大小
  • % of Total Download Size:文件的 download size 占总的 APK 的百分比

图片资源

图片资源在 APP 中的占有的比例还是很高的,针对图片资源的优化也是最简单的,最容易看到效果的。大多数 APP 的图片资源主要都是 PNG 和 JPG,主要操作方法如下:

  • 删除无用资源
  • 用 TinyPNG 压缩 PNG 图片,并将能转成 JPG 的图片进行转换
  • 压缩 JPG 图片
  • 使用 WebP 图片

PS:
WebP 格式,google 开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有 JPEG 的 2/3,并能节省大量的服务器带宽资源和数据空间,WebP 解析速度快,但是编码速度慢,Android 4.1 才开始对WebP有了比较稳定的部分支持(即大多数只支持不含 alpha 通道的 WebP 图片),Android 4.2 才基本完全支持 WebP。

代码

简单的情况:
启用 ProGuard 代码混淆,删除无用代码,无用的 JAR 包,以及无用 so 库等等,可以很有效的减少 APK 的大小。

复杂的情况有下面几种:

  1. 只使用了第三方 jar 包的很少部分的功能。

    可以选择把 jar 包中我们需要的内容提取出来,做一个精简版的 jar 包。还可以减少第三方 jar 包的升级,因为升级加了新特性包大小大概率要增加的

  2. 代码中实现的功能较为重复。

    解决方案是进行基础功能组件化,增强代码复用

  3. 使用的多个第三方 jar 包包含了相同的功能的不同库,或者是相同库的不同版本。

    比如 Glide 和 Fresco,可以选择修改源代码,使用同一个库的同一个版本,再重新打包。

  4. so 库过大或者 Dex 过大。

    使用动态加载 so 库的技术和 APK 插件化技术。

资源混淆

参照微信 Android 资源混淆打包工具,核心在于对 APK 中 resources.arsc 文件的修改,Android 项目中 res 目录下每个资源都有其对应的 ID,而 ID 在 R 文件下关联着资源名称,通过这些 ID 我们可以很方便的锁定某一项资源,而资源混淆的原理就在于对 ID 对应的资源路径进行优化处理(如将 res/drawable/xxx 修改成 res/drawable/a,或者修改为 r/d/a),通过这个方式可以大大减小 resources.arsc 文件的内容,从而达到减包的目的。